﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "GmStructureFactory.h"
#include "GbmpLineFamilyInstance.h"
#include "StructureBasicBeam.h"
#include "StructureBasicWall.h"
#include "StructureVariableSectionBeam.h"
#include "StructureVariableSectionWall.h"
#include "StructureVerticalColumn.h"
#include "StructureSlantedColumn.h"
#include "StructurePlateHole.h"
#include "StructureWallHole.h"
#include "StructureFloor.h"
#include "StructureRaftFoundation.h"
#include "StructureRoof.h"
#include "StructureInstanceBuildingStoreyData.h"
#include "DbObjectUtils.h"
#include "StructureInstanceJoinBehavior.h"
#include "StructureStripFoundation.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;

namespace
{
    GmStructureFactory s_factory;
}

GmStructureFactory::GmStructureFactory()
{
    m_pFactory = this;
}

GmStructureFactory::~GmStructureFactory()
{
    m_pFactory = nullptr;
}

Guid GmStructureFactory::GetClassGuidThroughBuiltInMethod(const IObject* pIObject) const
{
    if (const NdbObject* pNdbObject = dynamic_cast<const NdbObject*>(pIObject))
    {
        const NdbClassSchema * pNdbClassSchema = pNdbObject->GetClassSchema();
        GBMP_ASSERT(pNdbClassSchema);
        return pNdbClassSchema->GetClassId().GetGuid();
    }
    return Guid();
}

ISerializationBehavior* GmStructureFactory::GetBuiltInSerializationBehavior(const IObject* pIObject) const
{
    return DbObjectUtils::GetBuiltInSerializationBehavior(pIObject);
}

ICloneBehavior* GmStructureFactory::GetBuiltInCloneBehavior(const IObject* pIObject) const
{
    if (const NdbObject* pNdbObject = dynamic_cast<const NdbObject*>(pIObject))
    {
        return NdbCloneBehavior::Get(pNdbObject);
    }
    return nullptr;
}

IGbmpLineFamilyInstance* GmStructureFactory::CreateLineFamilyInstance(const LineFamilyInstanceInput* pInput, bool regenInstance)
{
    return GbmpLineFamilyInstance::Create(pInput, regenInstance);
}

IStructureBasicBeam* GmStructureFactory::CreateBasicBeam(const StructureBeamInput* pInput)
{
    return StructureBasicBeam::Create(pInput);
}

gcmp::IStructureBasicBeam* gcmp::GmStructureFactory::GetBasicBeam(IInstance* pInstance)
{
    return StructureBasicBeam::Get(pInstance);
}

const gcmp::IStructureBasicBeam* gcmp::GmStructureFactory::GetBasicBeam(const IInstance* pInstance)
{
    return StructureBasicBeam::Get(pInstance);
}

IStructureVariableSectionBeam* GmStructureFactory::CreateVariableSectionBeam(const StructureBeamInput* pInput)
{
    return StructureVariableSectionBeam::Create(pInput);
}

gcmp::IStructureVariableSectionBeam* gcmp::GmStructureFactory::GetVariableSectionBeam(IInstance* pInstance)
{
    return StructureVariableSectionBeam::Get(pInstance);
}

const gcmp::IStructureVariableSectionBeam* gcmp::GmStructureFactory::GetVariableSectionBeam(const IInstance* pInstance)
{
    return StructureVariableSectionBeam::Get(pInstance);
}

gcmp::IStructureBasicWall* gcmp::GmStructureFactory::CreateBasicWall(const StructureWallInput* pInput)
{
    return StructureBasicWall::Create(pInput);
}

gcmp::IStructureBasicWall* gcmp::GmStructureFactory::GetBasicWall(IInstance* pInstance)
{
    return StructureBasicWall::Get(pInstance);
}

const gcmp::IStructureBasicWall* gcmp::GmStructureFactory::GetBasicWall(const IInstance* pInstance)
{
    return StructureBasicWall::Get(pInstance);
}

gcmp::IStructureVariableSectionWall* gcmp::GmStructureFactory::CreateVariableSectionWall(const StructureWallInput* pInput)
{
    return StructureVariableSectionWall::Create(pInput);
}

gcmp::IStructureVariableSectionWall* gcmp::GmStructureFactory::GetVariableSectionWall(IInstance* pInstance)
{
    return StructureVariableSectionWall::Get(pInstance);
}

const gcmp::IStructureVariableSectionWall* gcmp::GmStructureFactory::GetVariableSectionWall(const IInstance* pInstance)
{
    return StructureVariableSectionWall::Get(pInstance);
}

IStructureVerticalColumn* GmStructureFactory::CreateVerticalColumn(const StructureColumnInput* pInput)
{
    return StructureVerticalColumn::Create(pInput);
}

gcmp::IStructureVerticalColumn* gcmp::GmStructureFactory::GetVerticalColumn(IInstance* pInstance)
{
    return StructureVerticalColumn::Get(pInstance);
}

const gcmp::IStructureVerticalColumn* gcmp::GmStructureFactory::GetVerticalColumn(const IInstance* pInstance)
{
    return StructureVerticalColumn::Get(pInstance);
}

IStructureSlantedColumn* GmStructureFactory::CreateSlantedColumn(const StructureColumnInput* pInput)
{
    return StructureSlantedColumn::Create(pInput);
}

gcmp::IStructureSlantedColumn* gcmp::GmStructureFactory::GetSlantedColumn(IInstance* pInstance)
{
    return StructureSlantedColumn::Get(pInstance);
}

const gcmp::IStructureSlantedColumn* gcmp::GmStructureFactory::GetSlantedColumn(const IInstance* pInstance)
{
    return StructureSlantedColumn::Get(pInstance);
}

gcmp::IStructureFloor* gcmp::GmStructureFactory::CreateStructureFloor(const StructureProfileInstanceGeometryInput* pInput)
{
    return StructureFloor::Create(pInput);
}

gcmp::IStructureFloor* gcmp::GmStructureFactory::EditStructureFloor(const StructureProfileInstanceEditElementInput* pInput)
{
    return StructureFloor::Edit(pInput);
}

gcmp::IStructureFloor* gcmp::GmStructureFactory::EditStructureFloor(const StructureProfileInstanceEditGeometryInput* pInput)
{
    return StructureFloor::Edit(pInput);
}

gcmp::IStructureFloor* gcmp::GmStructureFactory::CreateStructureFloor(const StructureProfileInstanceElementInput* pInput)
{
    return StructureFloor::Create(pInput);
}

gcmp::IStructureFloor* gcmp::GmStructureFactory::GetStructureFloor(IInstance* pInstance)
{
    return StructureFloor::Get(pInstance);
}

const gcmp::IStructureFloor* gcmp::GmStructureFactory::GetStructureFloor(const IInstance* pInstance)
{
    return StructureFloor::Get(pInstance);
}

gcmp::IStructurePlateHole* gcmp::GmStructureFactory::CreateStructurePlateHole(const StructurePlateHoleGeometryInput* pInput)
{
    return StructurePlateHole::Create(pInput);
}

gcmp::IStructurePlateHole* gcmp::GmStructureFactory::CreateStructurePlateHole(const StructurePlateHoleElementInput* pInput)
{
    return StructurePlateHole::Create(pInput);
}

gcmp::IStructurePlateHole* gcmp::GmStructureFactory::EditStructurePlateHole(const StructurePlateHoleEditGeometryInput* pInput)
{
    return StructurePlateHole::Edit(pInput);
}

gcmp::IStructurePlateHole* gcmp::GmStructureFactory::EditStructurePlateHole(const StructurePlateHoleEditElementInput* pInput)
{
    return StructurePlateHole::Edit(pInput);
}

gcmp::IStructurePlateHole* gcmp::GmStructureFactory::GetStructurePlateHole(IInstance* pInstance)
{
    return StructurePlateHole::Get(pInstance);
}

const gcmp::IStructurePlateHole* gcmp::GmStructureFactory::GetStructurePlateHole(const IInstance* pInstance)
{
    return StructurePlateHole::Get(pInstance);
}

gcmp::IStructureRaftFoundation* gcmp::GmStructureFactory::CreateRaftFoundation(const StructureRaftFoundationElementInput* pInput)
{
    return StructureRaftFoundation::Create(pInput);
}

gcmp::IStructureRaftFoundation* gcmp::GmStructureFactory::CreateRaftFoundation(const StructureRaftFoundationGeometryInput* pInput)
{
    return StructureRaftFoundation::Create(pInput);
}

gcmp::IStructureRaftFoundation* gcmp::GmStructureFactory::EditRaftFoundation(const StructureProfileInstanceEditElementInput* pInput)
{
    return StructureRaftFoundation::Edit(pInput);
}

gcmp::IStructureRaftFoundation* gcmp::GmStructureFactory::EditRaftFoundation(const StructureProfileInstanceEditGeometryInput* pInput)
{
    return StructureRaftFoundation::Edit(pInput);
}

gcmp::IStructureRaftFoundation* gcmp::GmStructureFactory::GetRaftFoundation(IInstance* pInstance)
{
    return StructureRaftFoundation::Get(pInstance);
}

const gcmp::IStructureRaftFoundation* gcmp::GmStructureFactory::GetRaftFoundation(const IInstance* pInstance)
{
    return StructureRaftFoundation::Get(pInstance);
}

IStructureStripFoundation* gcmp::GmStructureFactory::CreateStripFoundation(const StructureStripFoundationInput* pInput)
{
    return StructureStripFoundation::Create(pInput);
}

gcmp::IStructureRoof* gcmp::GmStructureFactory::CreateStructureRoof(const StructureRoofInput* pInput)
{
    return StructureRoof::Create(pInput);
}

gcmp::IStructureRoof* gcmp::GmStructureFactory::EditStructureRoof(const StructureRoofEditInput* pInput)
{
    return StructureRoof::Edit(pInput);
}

gcmp::IStructureRoof* gcmp::GmStructureFactory::GetStructureRoof(IInstance* pInstance)
{
    return StructureRoof::Get(pInstance);
}

const gcmp::IStructureRoof* gcmp::GmStructureFactory::GetStructureRoof(const IInstance* pInstance)
{
    return StructureRoof::Get(pInstance);
}

gcmp::IStructureWallHole* gcmp::GmStructureFactory::CreateWallHole(const StructureWallHoleInput* pInput)
{
    return StructureWallHole::Create(pInput);
}

gcmp::IStructureInstanceBuildingStoreyData* gcmp::GmStructureFactory::CreateStructureInstanceBuildingStoreyData(IInstance* pInstance,ElementId buildingStoreyId)
{
    return StructureInstanceBuildingStoreyData::Create(pInstance, buildingStoreyId);
}

gcmp::IStructureInstanceBuildingStoreyData* gcmp::GmStructureFactory::GetStructureInstanceBuildingStoreyData(IInstance* pInstance)
{
    return StructureInstanceBuildingStoreyData::Get(pInstance);
}

const gcmp::IStructureInstanceBuildingStoreyData* gcmp::GmStructureFactory::GetStructureInstanceBuildingStoreyData(const IInstance* pInstance)
{
    return StructureInstanceBuildingStoreyData::Get(pInstance);
}

OwnerPtr<IElementJoinBehavior> gcmp::GmStructureFactory::CreateInstanceJoinBehavior(IDocument* pDoc, JoinType joinType, bool isChangeJoinTypeAllowed)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(joinType == JoinType::Abut || joinType == JoinType::SquareOff || joinType == JoinType::TType, L"不支持的连接类型",L"GDMPLab",L"2024-03-30");
    return NEW_AS_OWNER_PTR(StructureInstanceJoinBehavior, pDoc, joinType, isChangeJoinTypeAllowed);
}
